package bai.publicwelfare_backend.controller.user;


import bai.publicwelfare_backend.common.utils.JwtUtil;
import bai.publicwelfare_backend.common.utils.Result;
import bai.publicwelfare_backend.exception.BusinessException;
import bai.publicwelfare_backend.exception.ErrorCode;
import bai.publicwelfare_backend.pojo.vo.user.AuthVO;
import com.auth0.jwt.JWT;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.ZoneId;
import java.util.Date;
import java.util.concurrent.TimeUnit;

//刷新令牌
@RestController
@RequestMapping("/token")
public class TokenController {

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
//    刷新令牌执行
    @GetMapping("/refresh")
    public Result<AuthVO> refresh(
            @RequestHeader("Authorization") String refreshToken // 从Header获取
    ) {
        // 1. 解析RefreshToken（不验证过期）
        DecodedJWT jwt = JWT.decode(refreshToken);

        // 检查是否RefreshToken类型
        if (!jwtUtil.isRefreshToken(refreshToken)) {
            throw new BusinessException(ErrorCode.TOKEN_TYPE_INVALID);
        }

        Long userId = jwt.getClaim("userId").asLong();

        // 2. 检查是否过期（显式验证）
        if (jwt.getExpiresAt().before(new Date())) {
            throw new BusinessException(ErrorCode.TOKEN_EXPIRED);
        }

        // 3. 验证Redis中的RefreshToken是否匹配
        String storedToken = redisTemplate.opsForValue().get("refresh:" + userId);
        if (!refreshToken.equals(storedToken)) {
            throw new BusinessException(ErrorCode.REFRESH_TOKEN_INVALID);
        }

        // 4. 生成新AccessToken（RefreshToken不变）
        String newAccessToken = JwtUtil.generateToken(userId, jwt.getClaim("version").asInt(), 1, TimeUnit.DAYS, "accessToken");
        String newRefreshToken  = JwtUtil.generateToken(userId, jwt.getClaim("version").asInt(), 7, TimeUnit.DAYS, "refreshToken");

        redisTemplate.delete("refresh:" + userId); // 先删除旧Token
        redisTemplate.opsForValue().set(
                "refresh:" + userId,
                newRefreshToken,
                7, TimeUnit.DAYS
        );

        return Result.success(new AuthVO(
                newAccessToken,
                refreshToken,
                null, // 可以不返回用户名
                userId,
                JwtUtil.getExpiryDate(newAccessToken).toInstant()
                        .atZone(ZoneId.systemDefault())
                        .toLocalDateTime()
        ));
    }
//    校验令牌合法性
    @GetMapping("/verifylogin")
    public Result<Boolean> verifyLogin(
            @RequestHeader("Authorization") String accessToken // 从Header获取
    ) {
        DecodedJWT decodedJWT = JWT.decode(accessToken);
        Integer version = decodedJWT.getClaim("version").asInt();
        Boolean results = jwtUtil.validateToken(accessToken, version);
        return Result.success(results);
    }
}
